# Title: 微信云鸽提单工具-云窍
# Params: start_time|one_str|2024-08-02, end_time|one_str|2024-08-08

import datetime
import json
import os
import random
import re
import socket
import time

import requests
from urllib.parse import urlparse, parse_qs
# from script import event_pb2
import base64
import python_calamine
from DrissionPage import ChromiumPage, ChromiumOptions

from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder

_runtime_version.ValidateProtobufRuntimeVersion(
    _runtime_version.Domain.PUBLIC,
    5,
    27,
    3,
    '',
    'event.proto'
)
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()

DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
    b'\n\x0b\x65vent.proto\",\n\x05\x45vent\x12\x0e\n\x06msg_id\x18\x01 \x01(\t\x12\x13\n\x04msgs\x18\x02 \x03(\x0b\x32\x05.Msgs\"\x87\x01\n\x04Msgs\x12\x0e\n\x06msg_id\x18\x01 \x01(\t\x12\x10\n\x08msg_type\x18\x02 \x01(\t\x12\x19\n\x07\x65header\x18\x03 \x01(\x0b\x32\x08.EHeader\x12\x10\n\x08msg_body\x18\x04 \x01(\x0c\x12\x16\n\x06traces\x18\x05 \x03(\x0b\x32\x06.Trace\x12\x18\n\x05rules\x18\x06 \x03(\x0b\x32\t.RuleInfo\"\n\n\x08Standard\"\x93\x03\n\x06Ticket\x12\x19\n\x11tkt_schedule_time\x18\x01 \x01(\t\x12\x10\n\x08tkt_rule\x18\x02 \x01(\t\x12\x12\n\ntkt_sender\x18\x03 \x01(\t\x12\x17\n\x0ftkt_send_status\x18\x04 \x01(\x05\x12\x19\n\x11tkt_failed_reason\x18\x05 \x01(\t\x12\x12\n\ntkt_status\x18\x06 \x01(\x05\x12\x0e\n\x06tkt_no\x18\x07 \x01(\t\x12\x19\n\x11tkt_urgency_level\x18\x08 \x01(\x05\x12\x14\n\x0ctkt_deadline\x18\t \x01(\t\x12\x18\n\x10tkt_handler_rule\x18\n \x01(\t\x12\x0e\n\x06tkt_t1\x18\x0b \x01(\t\x12\x15\n\rtkt_t1_cclist\x18\x0c \x01(\t\x12\x0e\n\x06tkt_t2\x18\r \x01(\t\x12\x15\n\rtkt_t2_cclist\x18\x0e \x01(\t\x12\x10\n\x08tkt_time\x18\x0f \x01(\t\x12\x1a\n\x12tkt_handle_timeout\x18\x10 \x01(\x05\x12\x14\n\x0ctkt_distance\x18\x11 \x01(\x05\x12\x13\n\x0btkt_rule_id\x18\x12 \x01(\x05\"\t\n\x07Project\"\r\n\x0bPreProccess\"\x08\n\x06Notify\"\t\n\x07\x43ircuit\"\r\n\x0b\x44\x61taCollect\"\x0f\n\rEffectCircuit\"\x10\n\x0e\x45\x66\x66\x65\x63tCustomer\"\n\n\x08\x43ustomer\"\t\n\x07Service\"\n\n\x08Relation\"\x0e\n\x0cGeogLocation\"\x0e\n\x0c\x44\x61taBaseTime\"\r\n\x0bPowerTicket\"\x06\n\x04\x41rea\"\x0f\n\rAutoScheduler\"\x0b\n\tSupervise\"\r\n\x0b\x45ventTicket\"\x0c\n\nRootAlarms\"\x0c\n\nCorrAlarms\"\x10\n\x0e\x43omplainTicket\"\xd0\x1f\n\x06\x44\x65tail\x12\x1b\n\tfixHeader\x18\x01 \x01(\x0b\x32\x08.EHeader\x12\x11\n\tvendor_id\x18\x02 \x01(\x05\x12\x13\n\x0bvendor_name\x18\x03 \x01(\t\x12\x0e\n\x06obj_id\x18\x04 \x01(\t\x12\x10\n\x08obj_name\x18\x05 \x01(\t\x12\x10\n\x08obj_type\x18\x06 \x01(\x05\x12\x14\n\x0cobj_sub_type\x18\x07 \x01(\x05\x12\x11\n\tobj_level\x18\x08 \x01(\x05\x12\x0e\n\x06obj_ip\x18\t \x01(\t\x12\x0f\n\x07sobj_id\x18\n \x01(\t\x12\x11\n\tsobj_name\x18\x0b \x01(\t\x12\x11\n\tsobj_type\x18\x0c \x01(\x05\x12\x15\n\rsobj_sub_type\x18\r \x01(\x05\x12\x12\n\nsobj_level\x18\x0e \x01(\x05\x12\x16\n\x0enetwork_type_1\x18\x0f \x01(\x05\x12\x16\n\x0enetwork_type_2\x18\x10 \x01(\x05\x12\x13\n\x0bproj_status\x18\x11 \x01(\x05\x12\x16\n\x0eregion_l1_name\x18\x12 \x01(\t\x12\x16\n\x0eregion_l2_name\x18\x13 \x01(\t\x12\x16\n\x0eregion_l3_name\x18\x14 \x01(\t\x12\x16\n\x0eregion_l4_name\x18\x15 \x01(\t\x12\x16\n\x0eregion_l5_name\x18\x16 \x01(\t\x12\x13\n\x0blocate_info\x18\x17 \x01(\t\x12\x0e\n\x06\x65_type\x18\x18 \x01(\x05\x12\x12\n\ne_sub_type\x18\x19 \x01(\x05\x12\x13\n\x0bvendor_type\x18\x1a \x01(\t\x12\x17\n\x0fvendor_severity\x18\x1b \x01(\t\x12\x0f\n\x07\x65_title\x18\x1c \x01(\t\x12\x16\n\x0eprobable_cause\x18\x1d \x01(\t\x12\x14\n\x0corg_event_id\x18\x1e \x01(\t\x12\x12\n\nevent_text\x18\x1f \x01(\t\x12\x15\n\ruser_severity\x18  \x01(\x05\x12\x15\n\re_latest_time\x18! \x01(\t\x12\x10\n\x08\x61\x62n_type\x18\" \x01(\x05\x12\x10\n\x08group_id\x18# \x03(\t\x12\x12\n\nboard_type\x18$ \x01(\t\x12\x12\n\nlayer_rate\x18% \x01(\t\x12\x13\n\x0bsignal_rate\x18& \x01(\t\x12\x16\n\x0e\x61larm_aux_info\x18\' \x01(\t\x12\x16\n\x0enotify_up_flag\x18( \x01(\x05\x12\x16\n\x0e\x65_subject_type\x18) \x01(\x05\x12\x10\n\x08\x65ms_name\x18* \x01(\t\x12\x0f\n\x07\x65_value\x18+ \x01(\x05\x12\x0f\n\x07site_id\x18, \x01(\t\x12\x11\n\tsite_name\x18- \x01(\t\x12\x12\n\nsite_owner\x18. \x01(\t\x12\x17\n\x0fmachine_room_id\x18/ \x01(\t\x12\x19\n\x11machine_room_name\x18\x30 \x01(\t\x12\x10\n\x08vnf_flag\x18\x31 \x01(\x05\x12\x0f\n\x07vm_list\x18\x32 \x01(\t\x12\x0f\n\x07pm_list\x18\x33 \x01(\t\x12\x12\n\ncm_info_ex\x18\x34 \x01(\t\x12\x14\n\x0c\x66\x61ult_reason\x18\x35 \x01(\x05\x12\x17\n\x0f\x62usiness_sys_id\x18\x36 \x01(\t\x12\x19\n\x11\x62usiness_sys_name\x18\x37 \x01(\t\x12\x19\n\x11\x62usiness_sys_type\x18\x38 \x01(\x05\x12\x15\n\rdistal_obj_id\x18\x39 \x01(\t\x12\x17\n\x0f\x64istal_obj_name\x18: \x01(\t\x12\x17\n\x0f\x64istal_obj_type\x18; \x01(\x05\x12\x16\n\x0e\x64istal_sobj_id\x18< \x01(\t\x12\x18\n\x10\x64istal_sobj_name\x18= \x01(\t\x12\x18\n\x10\x64istal_sobj_type\x18> \x01(\x05\x12\x17\n\x0f\x64istal_loc_info\x18? \x01(\t\x12\x13\n\x0b\x63\x61ncel_time\x18@ \x01(\t\x12\x16\n\x0eopt_ack_status\x18\x41 \x01(\x05\x12\x14\n\x0copt_ack_time\x18\x42 \x01(\t\x12\x14\n\x0copt_ack_user\x18\x43 \x01(\t\x12\x17\n\x0fopt_cancel_user\x18\x44 \x01(\t\x12\x15\n\ropt_mark_flag\x18\x45 \x01(\x05\x12\x1b\n\x08standard\x18\x46 \x01(\x0b\x32\t.Standard\x12\x17\n\x06ticket\x18G \x01(\x0b\x32\x07.Ticket\x12\x19\n\x07project\x18H \x01(\x0b\x32\x08.Project\x12!\n\x0bpreProccess\x18I \x01(\x0b\x32\x0c.PreProccess\x12\x19\n\x08notifies\x18J \x03(\x0b\x32\x07.Notify\x12\x1a\n\x08\x63ircuits\x18K \x03(\x0b\x32\x08.Circuit\x12\x18\n\x02\x64\x63\x18L \x01(\x0b\x32\x0c.DataCollect\x12%\n\reffectCircuit\x18M \x01(\x0b\x32\x0e.EffectCircuit\x12\'\n\x0e\x65\x66\x66\x65\x63tCustomer\x18N \x01(\x0b\x32\x0f.EffectCustomer\x12\x1c\n\tcustomers\x18O \x03(\x0b\x32\t.Customer\x12\x1a\n\x08services\x18P \x03(\x0b\x32\x08.Service\x12\x1c\n\trelations\x18Q \x03(\x0b\x32\t.Relation\x12\x15\n\rdisp_group_id\x18R \x01(\t\x12\x17\n\x0f\x64isp_group_type\x18S \x01(\x05\x12\x11\n\tobj_alias\x18T \x01(\t\x12\x12\n\nsobj_alias\x18U \x01(\t\x12\x14\n\x0cuplevel_time\x18V \x01(\t\x12\x10\n\x08\x65_source\x18W \x01(\t\x12\x11\n\tobj_model\x18X \x01(\t\x12\x15\n\rcoverage_info\x18Y \x01(\t\x12\x12\n\ne_mgt_type\x18Z \x01(\x05\x12\x11\n\tsite_type\x18[ \x01(\x05\x12\x13\n\x0bsite_outage\x18\\ \x01(\x05\x12\x15\n\rbusiness_info\x18] \x01(\t\x12 \n\tgLocation\x18^ \x01(\x0b\x32\r.GeogLocation\x12\x1b\n\x13\x64istal_region_l1_id\x18_ \x01(\x05\x12\x1b\n\x13\x64istal_region_l2_id\x18` \x01(\x05\x12\x1b\n\x13\x64istal_region_l3_id\x18\x61 \x01(\x05\x12\x1b\n\x13\x64istal_region_l4_id\x18\x62 \x01(\t\x12\x1b\n\x13\x64istal_region_l5_id\x18\x63 \x01(\x05\x12\x19\n\x11machine_room_type\x18\x64 \x01(\x05\x12\x1a\n\x12\x64\x61ta_collect_delay\x18\x65 \x01(\x03\x12\x1b\n\x13probable_cause_text\x18\x66 \x01(\t\x12\x11\n\thost_list\x18g \x03(\t\x12\x14\n\x0cregion_l9_id\x18h \x01(\x05\x12\x16\n\x0eregion_l9_name\x18i \x01(\t\x12\x13\n\x0bregion_type\x18j \x01(\x05\x12\x19\n\x02\x64\x62\x18k \x01(\x0b\x32\r.DataBaseTime\x12\x12\n\ndistal_lat\x18l \x01(\x01\x12\x12\n\ndistal_lon\x18m \x01(\x01\x12\x10\n\x08\x61rea_ids\x18n \x03(\x05\x12\x1b\n\x13\x66\x61ult_reason_detail\x18o \x01(\t\x12\x16\n\x0eimportant_flag\x18p \x01(\x05\x12!\n\x0bpowerTicket\x18q \x01(\x0b\x32\x0c.PowerTicket\x12\x12\n\narea_level\x18r \x01(\x05\x12\x11\n\tnfvo_name\x18s \x01(\t\x12\x12\n\nscene_type\x18t \x01(\x05\x12\x18\n\x10\x64istal_obj_level\x18u \x01(\x05\x12\x10\n\x08\x61\x64\x64_info\x18v \x01(\t\x12\x13\n\x0bup_obj_name\x18w \x01(\t\x12\x10\n\x08\x65ms_type\x18x \x01(\x05\x12\x13\n\x0bsobj_status\x18y \x01(\x05\x12\x14\n\x05\x61reas\x18z \x03(\x0b\x32\x05.Area\x12\x1a\n\x12user_severity_rule\x18{ \x01(\x03\x12\x12\n\npower_type\x18| \x01(\t\x12\x15\n\rsend_tkt_flag\x18} \x01(\x05\x12\x15\n\x0cpass_cluster\x18\x80\x01 \x01(\t\x12\x1a\n\x11pass_sub_business\x18\x81\x01 \x01(\t\x12\x16\n\rpass_business\x18\x82\x01 \x01(\t\x12\x1a\n\x11\x64\x61ss_sub_business\x18\x83\x01 \x01(\t\x12\x16\n\rdass_business\x18\x84\x01 \x01(\t\x12\x15\n\x0c\x64\x61ss_cluster\x18\x85\x01 \x01(\t\x12\x12\n\tdass_plat\x18\x86\x01 \x01(\t\x12\x15\n\x0cobj_location\x18\x87\x01 \x01(\t\x12\x1e\n\x15pretkt_scheduler_time\x18\x88\x01 \x01(\t\x12\x1a\n\x11\x65oms_network_type\x18\x89\x01 \x01(\t\x12\x1b\n\x12\x64\x65rived_e_severity\x18\x8a\x01 \x01(\x05\x12\x1e\n\x15machine_room_type_tra\x18\x8b\x01 \x01(\x05\x12\x1e\n\x15machine_room_type_pon\x18\x8c\x01 \x01(\x05\x12\x16\n\rdistal_obj_ip\x18\x8d\x01 \x01(\t\x12\x1f\n\x16machine_room_type_busi\x18\x8e\x01 \x01(\x05\x12\x1b\n\x12\x63overage_regionl1s\x18\x8f\x01 \x03(\x05\x12\x12\n\tdptx_time\x18\x90\x01 \x01(\t\x12\x12\n\taprx_time\x18\x91\x01 \x01(\t\x12\x0f\n\x06\x65_uuid\x18\x92\x01 \x01(\t\x12&\n\rautoScheduler\x18\x93\x01 \x01(\x0b\x32\x0e.AutoScheduler\x12\x12\n\tdp_nodeid\x18\x94\x01 \x01(\t\x12\x10\n\x07site_no\x18\x95\x01 \x01(\t\x12\x1e\n\tsupervise\x18\x96\x01 \x01(\x0b\x32\n.Supervise\x12\x1d\n\x14severity_change_time\x18\x97\x01 \x01(\t\x12\x17\n\x0ehidden_trouble\x18\x98\x01 \x01(\x05\x12\x14\n\x0bremark_text\x18\x99\x01 \x01(\t\x12\x12\n\tup_obj_id\x18\x9a\x01 \x01(\t\x12\x19\n\x10\x65_handle_suggest\x18\x9b\x01 \x01(\t\x12\x12\n\te_country\x18\x9c\x01 \x01(\t\x12\x16\n\rresource_pool\x18\x9d\x01 \x01(\t\x12\x13\n\nrel_parent\x18\x9e\x01 \x01(\x05\x12\x16\n\re_parent_type\x18\x9f\x01 \x01(\x05\x12\x1c\n\x13generator_installed\x18\xa0\x01 \x01(\x05\x12\x11\n\x08\x65vent_no\x18\xa1\x01 \x01(\t\x12\x15\n\x0c\x64isturb_flag\x18\xa2\x01 \x01(\x05\x12\x14\n\x0b\x66ormer_e_id\x18\xa3\x01 \x01(\t\x12\x1f\n\x16\x63onfirm_eff_first_time\x18\xa8\x01 \x01(\t\x12 \n\x17\x63onfirm_eff_latest_time\x18\xa9\x01 \x01(\t\x12\x13\n\nshare_type\x18\xaa\x01 \x01(\x05\x12\x17\n\x0e\x62\x61ttery_life_m\x18\xab\x01 \x01(\x05\x12\x1e\n\x15rootalarm_obj_compare\x18\xac\x01 \x01(\x05\x12\x1f\n\x16rootalarm_type_compare\x18\xad\x01 \x01(\x05\x12#\n\x1arootalarm_network1_compare\x18\xae\x01 \x01(\x05\x12\x1c\n\x13\x65\x66\x66\x65\x63t_busi_compare\x18\xaf\x01 \x01(\x05\"\xeb\x01\n\tFixHeader\x12\x0c\n\x04\x65_id\x18\x01 \x01(\t\x12\r\n\x05\x65_cid\x18\x02 \x01(\t\x12\x0e\n\x06\x65_time\x18\x03 \x01(\t\x12\x10\n\x08\x65_status\x18\x04 \x01(\x05\x12\x14\n\x0cstd_severity\x18\x05 \x01(\x05\x12\x13\n\x0b\x63\x61ncel_mode\x18\x06 \x01(\x05\x12\x12\n\ne_rec_time\x18\x07 \x01(\t\x12\x0e\n\x06\x65_freq\x18\x08 \x01(\x05\x12\x0e\n\x06\x64\x63p_id\x18\t \x01(\x05\x12\x14\n\x0cregion_l1_id\x18\n \x01(\x05\x12\x14\n\x0cregion_l2_id\x18\x0b \x01(\x05\x12\x14\n\x0cregion_l3_id\x18\x0c \x01(\x05\"\xd7\x01\n\x07\x45Header\x12\x0c\n\x04\x65_id\x18\x01 \x01(\t\x12\r\n\x05\x65_cid\x18\x02 \x01(\t\x12\x0e\n\x06\x65_time\x18\x03 \x01(\t\x12\x14\n\x0cstd_severity\x18\x04 \x01(\x05\x12\x13\n\x0b\x63\x61ncel_mode\x18\x05 \x01(\x05\x12\x12\n\ne_rec_time\x18\x06 \x01(\t\x12\x0e\n\x06\x65_freq\x18\x07 \x01(\x05\x12\x0e\n\x06\x64\x63p_id\x18\x08 \x01(\x05\x12\x14\n\x0cregion_l1_id\x18\t \x01(\x05\x12\x14\n\x0cregion_l2_id\x18\n \x01(\x05\x12\x14\n\x0cregion_l3_id\x18\x0b \x01(\x05\"\x19\n\x05Trace\x12\x10\n\x08trace_id\x18\x01 \x01(\t\"\x1b\n\x08RuleInfo\x12\x0f\n\x07rule_id\x18\x01 \x01(\tb\x06proto3')

_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'event_pb2', _globals)
if not _descriptor._USE_C_DESCRIPTORS:
    DESCRIPTOR._loaded_options = None
    _globals['_EVENT']._serialized_start = 15
    _globals['_EVENT']._serialized_end = 59
    _globals['_MSGS']._serialized_start = 62
    _globals['_MSGS']._serialized_end = 197
    _globals['_STANDARD']._serialized_start = 199
    _globals['_STANDARD']._serialized_end = 209
    _globals['_TICKET']._serialized_start = 212
    _globals['_TICKET']._serialized_end = 615
    _globals['_PROJECT']._serialized_start = 617
    _globals['_PROJECT']._serialized_end = 626
    _globals['_PREPROCCESS']._serialized_start = 628
    _globals['_PREPROCCESS']._serialized_end = 641
    _globals['_NOTIFY']._serialized_start = 643
    _globals['_NOTIFY']._serialized_end = 651
    _globals['_CIRCUIT']._serialized_start = 653
    _globals['_CIRCUIT']._serialized_end = 662
    _globals['_DATACOLLECT']._serialized_start = 664
    _globals['_DATACOLLECT']._serialized_end = 677
    _globals['_EFFECTCIRCUIT']._serialized_start = 679
    _globals['_EFFECTCIRCUIT']._serialized_end = 694
    _globals['_EFFECTCUSTOMER']._serialized_start = 696
    _globals['_EFFECTCUSTOMER']._serialized_end = 712
    _globals['_CUSTOMER']._serialized_start = 714
    _globals['_CUSTOMER']._serialized_end = 724
    _globals['_SERVICE']._serialized_start = 726
    _globals['_SERVICE']._serialized_end = 735
    _globals['_RELATION']._serialized_start = 737
    _globals['_RELATION']._serialized_end = 747
    _globals['_GEOGLOCATION']._serialized_start = 749
    _globals['_GEOGLOCATION']._serialized_end = 763
    _globals['_DATABASETIME']._serialized_start = 765
    _globals['_DATABASETIME']._serialized_end = 779
    _globals['_POWERTICKET']._serialized_start = 781
    _globals['_POWERTICKET']._serialized_end = 794
    _globals['_AREA']._serialized_start = 796
    _globals['_AREA']._serialized_end = 802
    _globals['_AUTOSCHEDULER']._serialized_start = 804
    _globals['_AUTOSCHEDULER']._serialized_end = 819
    _globals['_SUPERVISE']._serialized_start = 821
    _globals['_SUPERVISE']._serialized_end = 832
    _globals['_EVENTTICKET']._serialized_start = 834
    _globals['_EVENTTICKET']._serialized_end = 847
    _globals['_ROOTALARMS']._serialized_start = 849
    _globals['_ROOTALARMS']._serialized_end = 861
    _globals['_CORRALARMS']._serialized_start = 863
    _globals['_CORRALARMS']._serialized_end = 875
    _globals['_COMPLAINTICKET']._serialized_start = 877
    _globals['_COMPLAINTICKET']._serialized_end = 893
    _globals['_DETAIL']._serialized_start = 896
    _globals['_DETAIL']._serialized_end = 4944
    _globals['_FIXHEADER']._serialized_start = 4947
    _globals['_FIXHEADER']._serialized_end = 5182
    _globals['_EHEADER']._serialized_start = 5185
    _globals['_EHEADER']._serialized_end = 5400
    _globals['_TRACE']._serialized_start = 5402
    _globals['_TRACE']._serialized_end = 5427
    _globals['_RULEINFO']._serialized_start = 5429
    _globals['_RULEINFO']._serialized_end = 5456


def check_port(host, port, timeout=3):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.settimeout(timeout)
        result = sock.connect_ex((host, port))
        print(result)
        return result == 0


def xlsx_to_dict(file: str, sheet_index=0) -> list[dict]:
    with open(file, 'rb') as file:
        workbook = python_calamine.CalamineWorkbook.from_filelike(file)
        _rows = iter(workbook.get_sheet_by_index(sheet_index).to_python())
        headers = list(map(str, next(_rows)))
        _values = [dict(zip(headers, row)) for row in _rows]

    return _values


def base_filter(content, value):
    for x in content:
        if x['管理IP'] and x['IPMIIP']:
            if x['管理IP'].strip() == value or x['IPMIIP'].strip() == value:
                return x


def get_4a_cookies():
    # 创建对象
    co = ChromiumOptions().set_local_port(1234)
    co.existing_only(True)
    page = ChromiumPage(addr_or_opts='co1')
    page_4a = page.get_tab(title='IT公司4A系统')
    if not page_4a:
        raise ValueError('未登录 IT公司4A系统')

    cookies = page_4a.cookies()
    cookie = list(map(lambda x: f"{x['name']}={x['value']}", cookies))
    cookie = '; '.join(cookie)

    return cookie


class ITCloud:
    def __init__(self):
        self.baseurl = 'http://172.17.104.123:12080'
        self.headers = {
            "content-type": "application/json",
        }

    def request_post(self, api: str, data):
        if not api.startswith('/'):
            api += '/'

        resp = requests.post(self.baseurl + api, headers=self.headers, data=data, verify=False, timeout=10)
        if resp.status_code != 200:
            print(resp.status_code)
            print(resp.headers)
            print(resp.text)
            raise ValueError(f'接口请求错误: {api}')
        return resp.cookies, resp.json(),

    def token(self, auth_ticket):
        uri = '/portal-auth-service/steward/v1/SteAAAAWsg/login'
        data = {
            "authTicket": auth_ticket
        }
        cookies, result = self.request_post(uri, json.dumps(data))
        token = result['data']['entity']['token']
        print(result)
        print('IT支撑云平台token: ', token)
        print('token: ', token)
        print('cookies', cookies)
        print(cookies.keys())
        print(cookies.values())
        return cookies, token


class Action4A:
    def __init__(self):
        self.baseurl = 'https://10.207.8.191:8443'
        self.headers = {
            "accept": "application/json, text/javascript, */*; q=0.01",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
            "cache-control": "no-cache",
            "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
            "pragma": "no-cache",
            "sec-ch-ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Microsoft Edge\";v=\"120\"",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"Windows\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-origin",
            "x-requested-with": "XMLHttpRequest",
            "cookie": get_4a_cookies(),
            "Referer": "https://10.207.8.191:8443/iga/page/myresources/mycollection/list.html?id=ffa4be5ab5944340ae237c8183e78a28",
            "Referrer-Policy": "strict-origin-when-cross-origin"
        }

    def request_post(self, api: str, data: dict):
        if not api.startswith('/'):
            api += '/'

        resp = requests.post(self.baseurl + api, headers=self.headers, data=data, verify=False, timeout=10)
        if resp.status_code != 200:
            print('---------------------error-----------------------')
            print(resp.status_code)
            print(resp.headers)
            print(resp.text)
            raise ValueError(f'接口请求错误: {api}')

        return resp.json()

    def get_sso_str(self):
        if not check_port('127.0.0.1', 1234):
            # _console('chrome浏览器端口没有开启')
            return 'chrome浏览器端口没有开启'
        if not os.path.exists('cache'):
            os.mkdir('cache')

        _console('获取4A 资源信息')
        rnd = random.random() * 10
        uri = f"/iga/sso/ssoLogin.do?rnd={rnd}"
        data = {
            'resId': '9146a678339e4f77834a8c6d6abe0b2a',
            'resProtocol': '',
            'accId': 'e58aeca9f79a475cbd40d6e64245246a',
            'accName': 'dwtangshuai',
            'clientId': 'cce41f5e97eb4f5da0ce49724b0e00b3',
            'isRoamRes': 1,
            'accPwd': '',
        }
        result = self.request_post(uri, data)

        sso_str = result['data']['ssoStr'].split('&')[0]
        data = base64.b64decode(sso_str).decode().split()[1]
        decoded = base64.b64decode(data).decode()
        url = re.findall(r'<url>(.*)</url>', decoded)[0]
        _console(f'已获取到4A资源信息sso：{url}')

        # 提取sso跳转页面的信息
        res = requests.get(url, allow_redirects=False)
        location_url = res.headers['Location']
        _console(f'location_url: {location_url}')
        parsed_url = urlparse(location_url)
        query_params = parse_qs(parsed_url.query)
        auth_ticket = query_params['authTicket'][0]
        auth_ticket = auth_ticket.replace(' ', '+')

        # 获取IT云token
        it_cloud = ITCloud()
        cookies, token = it_cloud.token(auth_ticket)
        JSESSIONID = cookies.get('JSESSIONID')

        # 获取云窍sso
        headers = {
            "accept": "*/*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
            "cache-control": "no-cache",
            "pragma": "no-cache",
            "x-auth-token": token,
            "cookie": f"JSESSIONID={JSESSIONID}; acctoken={token}",
            "Referer": "http://172.17.104.123:12080/steward/index.html",
            "Referrer-Policy": "strict-origin-when-cross-origin"
        }

        url = 'http://172.17.104.123:12080/portal-service/system/v1/SteUserWsg/getTicket?subAccount=dwtangshuai&product=yunqiao'
        resp = requests.get(url, headers=headers, verify=False)
        ticket = resp.json()['data']['entity']['ticket']

        _console(f'云窍ticket, {ticket}')
        return ticket


def is_port_open(host: str, port: int) -> bool:
    """检查指定的主机和端口是否开放"""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.settimeout(3)  # 设置超时时间为 3 秒
        try:
            sock.connect((host, port))
            return True
        except (socket.timeout, socket.error):
            return False


class YunQiao:
    def __init__(self):
        host = {
            '172.16.21.225': 80,
            '172.21.152.199': 10205
        }
        for ip, port in host.items():
            if is_port_open(ip, port):
                self.baseurl = f'http://{ip}:{port}'
                break

        # self.baseurl = 'http://172.21.152.199:10205'
        self.headers = {
            "accept": "application/json, text/plain, */*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
            "authorization": "Bearer bndoZDRFc29YU3pLVm1FcHRBNmhnUT09O3BrWkIzWnB1WkJBNkJQY2JuNGo4VmM0dHZZNU83OVhBWEdVdERTTDRnaitzeThxQjQxVjc3aWtwbyt2Q0pFdnBpVlJ5cDE5M1FDL0tleisycjd3WVdLMEw3U1JiNW1YMjV3K2JoTlo2V2ZlRVYrcFhPUDNQTU44YTRXbjAwOWp1bit0dkNmTW9SVU1ReWN6aDRpZGJEWFRXdU1oVVJNd1VNekNrRDhqR01IbkNiTGtJMFd2MVVNVjJPZkpvZ1RaSlgzU1JNdVRNUUpSWmxpOGI0ZmxNK1gyT1Vqa0RUYytUVWNRVmtkdlVGcnNYcUl5VVRnYTFVekdZOFloZ0JtMDBqYkdRQm0zN1VYbUVIdlV4VXhxeGQ0SGtVQ3JVaW1yei95K2ZqelA5d3VTMEpIZTlpTnlCenNuUDNmek9PaHRjZnBGTGlFMzduTVpBZGVXMjB1bTR5QmRBTUtqUnQvYVVubmNvcHdZQ1ZrTUhsS2I3Vy9HOGNMWHhXTW02NDZSL1JIMlZZYW9ScUQ0b3RJc3oxa0NRc3VmdUdRbkdoVldtdWlISlc0VVJVZURxa0xhV0FVakkvTVhPM1I5NVFvZjk3M0NLTTR1azB1OEVicGhwSU5iVDMzandGbi94R0tPQ201QnhvTVo5Yi9zc1pJRE1oSldkNDdOaHdaTXNDUEZmeEROVS80ejZ1djlvajdEZWkyeW5CdWU1TkV2OGNXTUdjR3lMVnA5Mm9SeVNDVm0rTGNmY0VuYW1zeDlkcDhZa1Q2VXVJdkt3NEVPOGtMSU4zN0dGM2xxaEFhT1k0UWxyU2lucktjcXpkUFRXajhzOExTYU9mMGZhd3dDZE9mYlpFbDV4S1Z0WXJiUWxhQXhjNldwSUsxRlpMS0U3K1RSeStnbHFhQ1d6Vk8ydGpPSDFTWTFGcjc2STRoSFg4ZTBDUnVIeCttWW9MYk4zelZDWHJRZnM4MzdMYnhKZGdRL2pFcjM0UmxzODFHRmZ5Vi8wblk4YU9VNTNtam1IdEc2cW9vZHFSOXZBMzF2RTM2WG1CWGJXWjB0dlFsdStDVzdqWEluTElpM2FMQVFnZnFXb0ZpY3IrV0Z0anJBU0dyT0IvMkdXTW5nOWZ1ZGJOcytHcmhQOW9PYUU2UGVtdG1Xc3IwcE5KRHZrMmFQYzl2VG5pdkN2YUI3SUV3QmJiZjVaM2ZHSVpzZzRmc2c3TkdCVTVoMlk5S1VOMHdqS2ZrSmt2cnM3UktmZk50Yz0",
            "cache-control": "no-cache",
            "companyid": "-1",
            "content-type": "application/json;charset=UTF-8",
            "language": "zh",
            "loginid": "dwtangshuai",
            "oauth2proxy": "true",
            "pragma": "no-cache",
            "userid": "893225b1-89a4-4132-afc0-5b8f600f0436",
            "cookie": "JSESSIONID=8DA884A81079B68B52983528122CF30E",
            "Referer": "http://172.21.152.199:10205/fmc/?hasHeader=false&viewType=5&viewName=PageAlarmSearch&token=bndoZDRFc29YU3pLVm1FcHRBNmhnUT09O3BrWkIzWnB1WkJBNkJQY2JuNGo4VmM0dHZZNU83OVhBWEdVdERTTDRnaitzeThxQjQxVjc3aWtwbyt2Q0pFdnBpVlJ5cDE5M1FDL0tleisycjd3WVdLMEw3U1JiNW1YMjV3K2JoTlo2V2ZlRVYrcFhPUDNQTU44YTRXbjAwOWp1bit0dkNmTW9SVU1ReWN6aDRpZGJEWFRXdU1oVVJNd1VNekNrRDhqR01IbkNiTGtJMFd2MVVNVjJPZkpvZ1RaSlgzU1JNdVRNUUpSWmxpOGI0ZmxNK1gyT1Vqa0RUYytUVWNRVmtkdlVGcnNYcUl5VVRnYTFVekdZOFloZ0JtMDBqYkdRQm0zN1VYbUVIdlV4VXhxeGQ0SGtVQ3JVaW1yei95K2ZqelA5d3VTMEpIZTlpTnlCenNuUDNmek9PaHRjZnBGTGlFMzduTVpBZGVXMjB1bTR5QmRBTUtqUnQvYVVubmNvcHdZQ1ZrTUhsS2I3Vy9HOGNMWHhXTW02NDZSL1JIMlZZYW9ScUQ0b3RJc3oxa0NRc3VmdUdRbkdoVldtdWlISlc0VVJVZURxa0xhV0FVakkvTVhPM1I5NVFvZjk3M0NLTTR1azB1OEVicGhwSU5iVDMzandGbi94R0tPQ201QnhvTVo5Yi9zc1pJRE1oSldkNDdOaHdaTXNDUEZmeEROVS80ejZ1djlvajdEZWkyeW5CdWU1TkV2OGNXTUdjR3lMVnA5Mm9SeVNDVm0rTGNmY0VuYW1zeDlkcDhZa1Q2VXVJdkt3NEVPOGtMSU4zN0dGM2xxaEFhT1k0UWxyU2lucktjcXpkUFRXajhzOExTYU9mMGZhd3dDZE9mYlpFbDV4S1Z0WXJiUWxhQXhjNldwSUsxRlpMS0U3K1RSeStnbHFhQ1d6Vk8ydGpPSDFTWTFGcjc2STRoSFg4ZTBDUnVIeCttWW9MYk4zelZDWHJRZnM4MzdMYnhKZGdRL2pFcjM0UmxzODFHRmZ5Vi8wblk4YU9VNTNtam1IdEc2cW9vZHFSOXZBMzF2RTM2WG1CWGJXWjB0dlFsdStDVzdqWEluTElpM2FMQVFnZnFXb0ZpY3IrV0Z0anJBU0dyT0IvMkdXTW5nOWZ1ZGJOcytHcmhQOW9PYUU2UGVtdG1Xc3IwcE5KRHZrMmFQYzl2VG5pdkN2YUI3SUV3QmJiZjVaM2ZHSVpzZzRmc2c3TkdCVTVoMlk5S1VOMHdqS2ZrSmt2cnM3UktmZk50Yz0&access-token=bndoZDRFc29YU3pLVm1FcHRBNmhnUT09O3BrWkIzWnB1WkJBNkJQY2JuNGo4VmM0dHZZNU83OVhBWEdVdERTTDRnaitzeThxQjQxVjc3aWtwbyt2Q0pFdnBpVlJ5cDE5M1FDL0tleisycjd3WVdLMEw3U1JiNW1YMjV3K2JoTlo2V2ZlRVYrcFhPUDNQTU44YTRXbjAwOWp1bit0dkNmTW9SVU1ReWN6aDRpZGJEWFRXdU1oVVJNd1VNekNrRDhqR01IbkNiTGtJMFd2MVVNVjJPZkpvZ1RaSlgzU1JNdVRNUUpSWmxpOGI0ZmxNK1gyT1Vqa0RUYytUVWNRVmtkdlVGcnNYcUl5VVRnYTFVekdZOFloZ0JtMDBqYkdRQm0zN1VYbUVIdlV4VXhxeGQ0SGtVQ3JVaW1yei95K2ZqelA5d3VTMEpIZTlpTnlCenNuUDNmek9PaHRjZnBGTGlFMzduTVpBZGVXMjB1bTR5QmRBTUtqUnQvYVVubmNvcHdZQ1ZrTUhsS2I3Vy9HOGNMWHhXTW02NDZSL1JIMlZZYW9ScUQ0b3RJc3oxa0NRc3VmdUdRbkdoVldtdWlISlc0VVJVZURxa0xhV0FVakkvTVhPM1I5NVFvZjk3M0NLTTR1azB1OEVicGhwSU5iVDMzandGbi94R0tPQ201QnhvTVo5Yi9zc1pJRE1oSldkNDdOaHdaTXNDUEZmeEROVS80ejZ1djlvajdEZWkyeW5CdWU1TkV2OGNXTUdjR3lMVnA5Mm9SeVNDVm0rTGNmY0VuYW1zeDlkcDhZa1Q2VXVJdkt3NEVPOGtMSU4zN0dGM2xxaEFhT1k0UWxyU2lucktjcXpkUFRXajhzOExTYU9mMGZhd3dDZE9mYlpFbDV4S1Z0WXJiUWxhQXhjNldwSUsxRlpMS0U3K1RSeStnbHFhQ1d6Vk8ydGpPSDFTWTFGcjc2STRoSFg4ZTBDUnVIeCttWW9MYk4zelZDWHJRZnM4MzdMYnhKZGdRL2pFcjM0UmxzODFHRmZ5Vi8wblk4YU9VNTNtam1IdEc2cW9vZHFSOXZBMzF2RTM2WG1CWGJXWjB0dlFsdStDVzdqWEluTElpM2FMQVFnZnFXb0ZpY3IrV0Z0anJBU0dyT0IvMkdXTW5nOWZ1ZGJOcytHcmhQOW9PYUU2UGVtdG1Xc3IwcE5KRHZrMmFQYzl2VG5pdkN2YUI3SUV3QmJiZjVaM2ZHSVpzZzRmc2c3TkdCVTVoMlk5S1VOMHdqS2ZrSmt2cnM3UktmZk50Yz0&refresh-token=UDk3OUkwUjZuN2hnTnpBVVQxUW9tdz09O3YvMERDWTh1NG9TWjRKNFBXYVErakEyRXFNbFdmZWlwVWpFVUlHRWUyaGQ0T0Y0Y2tqVjdpV05hN2I1U1ErYndJUG9ZNEdJQVNoaFYvQndCaXRKdUtBeTZLK0lDWkgwa3laWU4xQjliOXJJSUN3SXBha0RBdm9lZ20vbS8wYjM0R21GVUVldTZiUExSSGw3RmlTVW1NQnl4RDVUelR6R2w4VGFhd2RHNzI5U0tXa1NxUFU3eHZlTDFZUStvbnZjRTFPeTVrNkFya0JmWUF6aXdsWDJDY1NmWjR3ajZ3VEU2Uk1JelNVY2ROOTJaUyszRW14MlZmQnIyYTBQZFRQYjdEUEEzelF3MG9odGkxYjdEdlo5elNydWkxdTMwSkJBeUt0aU54b3B3ZThiNlZKSGdIbFJSREtHMUl6NFFYUXhCQ21KN09iWEZKcUFKcGdDYm1GZ0d1OWFueUM3SGRnamZlOG9NWVFReUhHcFZRNHQ5S2VZY2owMFR1dHZVak83cnJBbWphNzUwbkozR3l4ZG01dkdaM3FzRXk1QjJmUEcvTmljSm9XaTRqajIyaUVUbmZ1UTJYaVA3bXR2SUFYUVc1SE5Edk1ZUWR3U2M4MVJQK2NBWGYvQ2lkYVhJd1IxdWZnbXc4TkJvL0tIYTNwQ1pabjNnWnNhcGxpeEpRc1hLbHdWcU95c3dUR3RXTWZPblBBR3FzanFSSG5CVWZ3NmFQOXhMSTVlZmxiV0tVWlZ4N1dTQlAyRWNMS0wwNEZFQ3JuL1lucXY2MDExRmJIYlliZEZDcWZhRkZqOHNrWXRHU3RpU3JGcXNQNE13NlNYQUpGVWt4Y3NsL3h3dlc2MDE0cDNrVi9EazhhQzBvQ05HVXEvOVh4NEJmc29UNGdUOXNCRUdxVWpvNEdzKzUvWTk2VU5MLyswSnI4VDVaSURVN0txK28xWjJPK2U1SUV6QktvRUliREk2RExLWllXYUNYVnlGTGVRczY0MzVmV1NWMWZJMHVjZVN3ZGdGT2ZjOXplQjVybW81RFRuUUxDNXBFelBqR0hZSmw3Z0l4cDdZdkdVWkpTUEhBekp1NjV6M1FNVGU0QTdtb21pR21PMWdvZTRoUUVqT1M1Um9NcWU4RVdWZkJUMVJ6OWoxWHRad0pIenBoYytTWnRsZ0hiUVQ5d2FjcUlLTCt5a0QyRkdNbnZ0U29BekN1MzdQanFnd0w4eVFndz09&originName=172.16.21.225/it-proxy&client-id=1&client-secret=BJit_321&is4a=true",
            "Referrer-Policy": "strict-origin-when-cross-origin"
        }

    def request_post(self, api: str, data: dict):
        if not api.startswith('/'):
            api += '/'

        resp = requests.post(self.baseurl + api, headers=self.headers, data=json.dumps(data), timeout=10)
        if resp.status_code != 200:
            print('---------------------error-----------------------')
            print(resp.status_code)
            print(resp.headers)
            print(resp.text)
            raise ValueError(f'接口请求错误: {api}')

        return resp.json()

    def alarm_serialized(self, alarms):
        """反序列化PB"""
        new_event = Event()
        new_event.ParseFromString(base64.b64decode(alarms))
        return new_event

    def alarm_list(self, start_time, end_time):
        """解析告警列表"""
        # now_date = datetime.datetime.now().date()
        # next_day = now_date + datetime.timedelta(days=1)
        uri = '/gateway/event-data-queryservice/queryservice/api/v1.0/alarmRecord?page=1&per_page=100&sort=-fixHeader.e_time'
        data = {
            "alarmOrigin": 0,
            "alarmSceneId": 0,
            "conditionMap": {
                "times_event": {
                    "fieldName": "times_event",
                    "startValue": f"{start_time} 00:00:00",
                    "endValue": f"{end_time} 23:59:59",
                    "not": False,
                    "opType": "between"
                },
                "fixHeader.region_l2_id": {
                    "fieldName": "fixHeader.region_l2_id",
                    "values": [
                        -1911320496
                    ],
                    "not": False,
                    "opType": "in"
                },
                "obj_type": {
                    "fieldName": "obj_type",
                    "values": [
                        201
                    ],
                    "not": False,
                    "opType": "in"
                },
                "fixHeader.std_severity": {
                    "fieldName": "fixHeader.std_severity",
                    "values": [
                        2,
                        3,
                        1
                    ],
                    "not": False,
                    "opType": "in"
                },
                "ticket.tkt_send_status": {
                    "fieldName": "ticket.tkt_send_status",
                    "values": [
                        5
                    ],
                    "not": False,
                    "opType": "in"
                }
            },
            "fieldNameArray": [],
            "regionL1Id": -1
        }
        result = self.request_post(uri, data)
        simple_alarms = result['winWrapper']['simpleAlarms']
        alarm_content = self.alarm_serialized(simple_alarms)
        alarms = []
        for i in alarm_content.msgs:
            detail = Detail()
            detail.ParseFromString(i.msg_body)
            alarms.append(detail)

        return alarms

    def token(self, refresh=False):
        with open(r'cache/yunqiao_token.txt', 'r+', encoding='utf-8') as f:
            access_token = f.read()
            if access_token:
                self.headers['Authorization'] = f'Bearer {access_token}'
                return

        action_4a = Action4A()
        ticket = action_4a.get_sso_str()

        timestamp_seconds = time.time()
        timestamp = int(timestamp_seconds * 1000)
        uri = f'/portal/auth_dist/oauth/token?data={timestamp}'
        data = {
            "client_id": "1",
            "client_secret": "BJit_321",
            "grant_type": "tenant_steward_ticket",
            "code": ticket
        }
        result = self.request_post(uri, data)
        access_token = result['access_token']

        if result['error_description'] == '票据无效！':
            _console('云窍token失效，请重新获取中')

        with open(r'cache/yunqiao_token.txt', 'w+', encoding='utf-8') as f:
            f.write(access_token)

        self.headers['Authorization'] = f'Bearer {access_token}'


template = r"""
【事件登记】
资产校验：{管理IP}(管理IP)
产品名称：机架式PC服务器
事件产生时间：{事件产生时间}
资源池：贵阳资源池
问题主题：贵池-{POD}-主机-{管理IP}-{故障类型}
事件描述：贵池-{POD}服务器{管理IP}{故障类型}、业务系统：{应用系统}、设备名称：{设备名称}、IPMI：{IPMIIP}、管理IP：{管理IP}、机型：{设备型号}、SN(序列号)：{设备序列号}、资产编号:暂未转资 、机位:贵阳数据中心{机房}机房{机柜编号}机柜{U位信息}、故障描述：{故障描述}、维保状态：{品牌}
一级部门：中移信息
二级部门：基础平台部
事件一级分类：设备故障
事件二级分类：主机
事件三级分类：{故障类型}
关联工单编号：{关联工单编号}
事件问题来源：{问题来源}
影响业务系统:否
优先级：低
联系人：{_name}
联系人电话：{_phone}
联系人邮箱：{_email}
事件处理人：赵文宬
"""

# fault_break = ['驱动器插槽磁盘在线解除', 'ping探测丢包率100%', 'RAID 组阵列失效']

fault_map = {
    '物理服务器磁盘告警': '硬盘故障',
    '物理服务器内存告警': '内存故障',
    '检测到存储设备故障': '硬盘故障',
    '【收敛告警】物理服务器多块磁盘故障': '硬盘故障',
    '物理服务器内存故障': '内存故障',
    '物理服务器电源告警': '电源故障',
    '【收敛告警】物理服务器内存告警5分钟出现2条及以上': '内存故障',
    '【收敛告警】物理服务器电源告警同网元5分钟触发2条及以上': '电源故障',
    '发生不可纠正的内存 ECC 错误': '内存故障',
    '物理服务器处理器告警': 'CPU故障',
    '物理服务器CPU故障': 'CPU故障',

}


def main():
    if not start_time or not end_time:
        return '未提供日期筛选'

    total_servers = xlsx_to_dict("depository/台账/IT云贵池设备台账.xlsx", 0)
    yun_qiao = YunQiao()
    yun_qiao.token()
    alarm_data = yun_qiao.alarm_list(start_time, end_time)

    output = []
    print(f'总数：{len(alarm_data)}')
    for detail in alarm_data:
        print(detail)
        if detail.opt_ack_status != 1:
            continue
        if detail.e_title not in fault_map:
            _console(f'未识别告警类型：{detail.e_title}')
            continue

        net_ip = detail.obj_ip
        e_data = base_filter(total_servers, net_ip)
        event_text = detail.event_text
        if '原始正文' in event_text:
            event_text = event_text[0:event_text.index('原始正文')]

        # if fault_map[detail.e_title] == '硬盘故障':
        #     event_text += f'、序列号：{}'
        print(detail.fixHeader.e_time)
        data = {'管理IP': e_data['管理IP'], '事件产生时间': detail.fixHeader.e_time,
                'POD': re.search(r'-(P.*)\(', detail.region_l3_name).group(1), '故障类型': fault_map[detail.e_title],
                '应用系统': detail.business_sys_name, '设备名称': e_data['设备名称'], 'IPMIIP': e_data['IPMIIP'],
                '设备型号': e_data['设备型号'], '设备序列号': e_data['设备序列号'], '机房': e_data['机房'],
                '机柜编号': e_data['机柜编号'], 'U位信息': e_data['U位信息'], '故障描述': event_text,
                '品牌': e_data['品牌'], '问题来源': '告警同步', '关联工单编号': detail.ticket.tkt_no, '_name': _name,
                '_phone': _phone, '_email': _email}
        result = template.format(**data)
        output.append(result)

    if not output:
        return '没有派过单的告警'
    return ''.join(output)

# if __name__ == '__main__':
#     # get_browser()
#     _console = print
#
#     print(main())
